package cn.justforchris.system.service.impl;



import cn.justforchris.blog.domain.ArticleType;
import cn.justforchris.system.domain.Menu;
import cn.justforchris.system.mapper.MenuMapper;
import cn.justforchris.system.query.MenuQuery;
import cn.justforchris.system.service.IMenuService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Transactional(readOnly = true,propagation = Propagation.SUPPORTS)
@CacheConfig(cacheNames = "Menu")
public class MenuServiceImpl implements IMenuService {

    @Autowired
    private MenuMapper menuMapper;
    @Override
    @Transactional
    @CacheEvict(key = "'menuTree'")
    public void insertMenu(Menu menu) {
        menuMapper.insertMenu(menu);
    }

    @Override
    @Transactional
    @CacheEvict(key = "'menuTree'")
    public void updateMenu(Menu menu) {
        menuMapper.updateMenu(menu);
    }

    @Override
    @Transactional
    @CacheEvict(key = "'menuTree'")
    public void deleteMenu(Long id) {
        menuMapper.deleteMenu(id);
    }

    @Override
    @Transactional
    @CacheEvict(key = "'menuTree'")
    public void patchDelete(Long[] ids) {
        menuMapper.patchDelete(ids);
    }

    @Override
    public Menu getMenuById(Long id) {
        return menuMapper.getMenuById(id);
    }

    @Override
    public List<Menu> getAll() {
        return menuMapper.getAll();
    }

    @Override
    public PageInfo<Menu> queryPage(MenuQuery queryPage) {
        PageHelper.startPage(queryPage.getCurrentPage(),queryPage.getPageSize());
        List<Menu> data = menuMapper.queryPage(queryPage);
        /*
        这里获取到的是符合传入参数currentpage和pagesize的数据,也就是说,如果不传pagesize就只有五条因为怕个size如果不传入的话就是5
        但是如果有pagesize传入就根据传入数据来
        */
        return new PageInfo<>(data);
        /*这里面就包含了pagehelper帮忙计算出来的total(总共多少条,和根据分页提取出的数据)*/
    }

    @Override
    @Cacheable(key = "'menuTree'")
    public List<Menu> getTypeTree() {

        return typeTree();
    }

    private List<Menu> typeTree() {
        /*第一步,获取所有的数据对象*/
        List<Menu> types = menuMapper.getAll();
        /*为了提高效率并且,容易获取到父类型对象,所以创建一个map集合用来存放id和对象*/
        Map<Long,Menu> map = new HashMap<>();
        /*循环获取到的数据对象,将对象放入map集合中*/
        for (Menu type : types) {
            map.put(type.getId(),type);
        }
        /*第三步,创建一个集合用于存放父类型数据对象*/
        List<Menu> typeTree = new ArrayList<>();
        /*遍历集合types判断是否有父类型,如果没有就将当前对象放入集合中*/
        for (Menu type : types) {
            if (type.getParentId()==null){
                typeTree.add(type);
            }else {
                /*如果有父类型,就通过父类型id获取到父类型对象,然后将当前对象放入父类型对象的children集合中*/
                /*不过,为了避免空指针异常,需要判断父类型是否存在*/
                Menu parentType = map.get(type.getParentId());
                if (parentType!=null) {
                    List<Menu> children = parentType.getChildren();
                    children.add(type);
                }
            }
        }
        return typeTree;
    }
}
